package org.xx.armory.service.security.impl;

import com.google.code.kaptcha.GimpyEngine;
import com.google.code.kaptcha.util.Configurable;
import com.jhlabs.image.RippleFilter;
import com.jhlabs.image.ShadowFilter;
import com.jhlabs.image.TransformFilter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public final class SimpleGimpy
        extends Configurable
        implements GimpyEngine {
    /**
     * {@inheritDoc}
     */
    @Override
    public BufferedImage getDistortedImage(final BufferedImage baseImage) {
        // draw lines over the image and/or text
        getConfig().getNoiseImpl().makeNoise(baseImage, .1f, .3f, .6f, .9f);

        ShadowFilter shadowFilter = new ShadowFilter();
        shadowFilter.setRadius(10);
        shadowFilter.setDistance(5);
        shadowFilter.setOpacity(1);

        final Random rand = new Random();

        final RippleFilter rippleFilter = new RippleFilter();
        rippleFilter.setWaveType(RippleFilter.SINE);
        // 设置横向波纹
        rippleFilter.setYAmplitude((rand.nextFloat() / 40 + .02f) * baseImage.getHeight());
        rippleFilter.setYWavelength(baseImage.getWidth());
        // 设置纵向波纹
        rippleFilter.setXAmplitude(getConfig().getTextProducerFontSize() * .1f);
        rippleFilter.setXWavelength(baseImage.getHeight() * (.12f + rand.nextFloat() / 20));
        // rippleFilter.setYWavelength(0);
        // rippleFilter.setXWavelength(rand.nextInt(7) + 8);
        // rippleFilter.setYWavelength(rand.nextInt(3) + 2);
        rippleFilter.setEdgeAction(TransformFilter.BILINEAR);

        final BufferedImage distortedImage = new BufferedImage(baseImage.getWidth(), baseImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
        final Graphics2D graph = (Graphics2D) distortedImage.getGraphics();
        try {
            graph.drawImage(shadowFilter.filter(rippleFilter.filter(baseImage, null), null), 0, 0, null, null);
        } finally {
            graph.dispose();
        }

        return distortedImage;
    }

}
